/* i6d_ucase_cl.c

   Client for i6d_ucase_sv.c: send each command-line argument as a datagram to
   the server, and then display the contents of the server's response datagram.

   ./i6d_ucase_cl 127.0.0.1 hello world

   for ipv6
   ./i6d_ucase_cl ::1 hello world
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>

#include "i6d_ucase.h"

static void errExit(char *msg) {
  perror(msg);
  exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]) {
  int sfd, j;
  size_t msgLen;
  ssize_t numBytes;
  char resp[BUF_SIZE];

  if (argc < 3 || strcmp(argv[1], "--help") == 0) {
    fprintf(stderr, "%s host-address msg...\n", argv[0]);
    exit(EXIT_FAILURE);
  }

#ifdef IPV6
  struct sockaddr_in6 svaddr;

  /* Create a datagram socket; send to an address in the IPv6 domain */
  sfd = socket(AF_INET6, SOCK_DGRAM, 0); /* Create client socket */
  if (sfd == -1) errExit("socket");

  memset(&svaddr, 0, sizeof(struct sockaddr_in6));
  svaddr.sin6_family = AF_INET6;
  svaddr.sin6_port = htons(PORT_NUM);
  if (inet_pton(AF_INET6, argv[1], &svaddr.sin6_addr) <= 0) {
    fprintf(stderr, "inet_pton failed for address '%s'", argv[1]);
    exit(EXIT_FAILURE);
  }
#else
  struct sockaddr_in svaddr;

  sfd = socket(AF_INET, SOCK_DGRAM, 0); /* Create client socket */
  if (sfd == -1) errExit("socket");

  bzero(&svaddr, sizeof(svaddr));
  svaddr.sin_family = AF_INET;
  svaddr.sin_port = htons(PORT_NUM);
  if (inet_pton(AF_INET, argv[1], &svaddr.sin_addr) <= 0) {
    fprintf(stderr, "inet_pton failed for address '%s'", argv[1]);
    exit(EXIT_FAILURE);
  }
#endif

  /* Send messages to server; echo responses on stdout */
  for (j = 2; j < argc; j++) {
    msgLen = strlen(argv[j]);
    if (sendto(sfd, argv[j], msgLen, 0, (struct sockaddr *)&svaddr,
               sizeof(struct sockaddr_in6)) != msgLen) {
      errExit("sendto");
    }

    /* recv message from server */
    numBytes = recvfrom(sfd, resp, BUF_SIZE, 0, NULL, NULL);
    if (numBytes == -1) errExit("recvfrom");

    printf("Response %d: %.*s\n", j - 1, (int)numBytes, resp);
  }

  exit(EXIT_SUCCESS);
}